package com.zonda.sampleretrofit2.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.zonda.sampleretrofit2.UnitUtils;

import java.util.Locale;

/**
 * 用于显示文章作者、发布时间、标识的控件；不支持padding属性
 *
 * @author zonda
 */
public class NewsListTagView extends View implements IBaseReleaser {

  private final static String LOG_TAG = "NewsListTagView";

  /**
   * 默认字体大小，单位: sp
   */
  private final static int DEFAULT_TEXT_SIZE = 8;

  /**
   * 默认间距，单位: dp
   */
  private final static int DEFAULT_PADDING_SIZE = 8;

  /**
   * 默认标签宽，单位：dp
   */
  private final static int DEFAULT_TAG_WIDTH = 22;

  /**
   * 默认标签高，单位：dp
   */
  private final static int DEFAULT_TAG_HEIGHT = 12;

  private String mNewsAuthorText;
  private String mNewsIssueText;
  private String mTagUri;

  private Drawable mNewsTagDrawable;

  /**
   * 作者名称字体大小，单位：px
   */
  private int mAuthorTextSize;

  /**
   * 发布时间字体大小，单位：px
   */
  private int mNewsIssueTextSize;

  /**
   * 元素之间的间距，单位：px
   */
  private int mElementsPadding;

  /**
   * 标签宽，单位：px
   */
  private int mTagWidth;

  /**
   * 标签高，单位：px
   */
  private int mTagHeight;

  /**
   * 字体颜色
   */
  private int mTextColor = Color.BLACK;


  private Paint mAuthorPaint;
  private Paint mIssuePaint;

  private final FontAspect mAuthorTextAspect = new FontAspect();
  private final FontAspect mIssueTextAspect = new FontAspect();

  private SimpleTarget<Bitmap> mTagTarget;

  public NewsListTagView(Context context) {
    super(context);
    init();
  }

  public NewsListTagView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    Log.i(LOG_TAG, "onMeasure widthMeasureSpec: " + widthMeasureSpec
        + " getSize: " + MeasureSpec.getSize(widthMeasureSpec)
        + " heightMeasureSpec: " + heightMeasureSpec + " getSize: "
        + MeasureSpec.getSize(heightMeasureSpec));

    Log.i(LOG_TAG, "onMeasure getPaddingTop: " + getPaddingTop());

    final float[] minimumDimension = new float[2];
    calculateMinimumDimension(minimumDimension);
    int measureWidth = resolveSize((int) (minimumDimension[0] + 0.5f), widthMeasureSpec);
    int measureHeight = resolveSize((int) (minimumDimension[1] + 0.5f), heightMeasureSpec);

    Log.i(LOG_TAG, "onMeasure measureWidth: " + measureWidth
        + " measureHeight: " + measureHeight);

    setMeasuredDimension(measureWidth, measureHeight);
  }

  private void calculateMinimumDimension(float[] measureDimension) {

    float measureWidth = .0f;
    float measureHeight = .0f;

    if (!TextUtils.isEmpty(mNewsAuthorText)) {
      measureWidth = mAuthorTextAspect.aspectWidth;
      measureHeight = mAuthorTextAspect.aspectHeight;
    }

    if (!TextUtils.isEmpty(mNewsIssueText)) {
      measureWidth += mIssueTextAspect.aspectWidth + mElementsPadding;
      measureHeight = Math.max(mIssueTextAspect.aspectHeight, measureHeight);
    }

    if (mNewsTagDrawable != null) {
      measureWidth += mTagWidth + mElementsPadding;
      measureHeight = Math.max(mTagHeight, measureHeight);
    }

    measureDimension[0] = measureWidth;
    measureDimension[1] = measureHeight;
  }

  @Override
  protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);
    Log.i(LOG_TAG, "onDraw width: " + getWidth() + " height: " + getHeight());
    Log.i(LOG_TAG, "onDraw getPaddingTop: " + getPaddingTop());
    final int width = getWidth();
    final int height = getHeight();

    canvas.clipRect(0, 0, width, height);

    float startX = 0;
    float statY = 0;
    if (!TextUtils.isEmpty(mNewsAuthorText)) {
      statY = height / 2.0f - (mAuthorTextAspect.aspectHeight) / 2.0f - mAuthorTextAspect.ascent;
      canvas.drawText(mNewsAuthorText, 0, statY, mAuthorPaint);
    }
    if (!TextUtils.isEmpty(mNewsIssueText)) {
      startX = mAuthorTextAspect.aspectWidth + mElementsPadding;
      statY = height / 2.0f - (mAuthorTextAspect.aspectHeight) / 2.0f - mIssueTextAspect.ascent;
      canvas.drawText(mNewsIssueText, startX, statY, mIssuePaint);
    }
    if (mNewsTagDrawable != null) {
      startX += mIssueTextAspect.aspectWidth + mElementsPadding;
      statY = (height - mTagHeight) / 2.0f;
      mNewsTagDrawable.setBounds((int) startX, (int) statY,
          (int) startX + mTagWidth, (int) statY + mTagHeight);
      mNewsTagDrawable.draw(canvas);
    }
  }

  private void init() {

    mAuthorPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.LINEAR_TEXT_FLAG);
    mIssuePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.LINEAR_TEXT_FLAG);
    mElementsPadding = UnitUtils.dip2px(getContext(), DEFAULT_PADDING_SIZE);
    mAuthorTextSize = UnitUtils.sp2px(getContext(), DEFAULT_TEXT_SIZE);
    mNewsIssueTextSize = mAuthorTextSize;
    mAuthorPaint.setTextSize(mAuthorTextSize);
    mAuthorPaint.setColor(mTextColor);
    mIssuePaint.setTextSize(mNewsIssueTextSize);
    mIssuePaint.setColor(mTextColor);

    mTagWidth = UnitUtils.dip2px(getContext(), DEFAULT_TAG_WIDTH);
    mTagHeight = UnitUtils.dip2px(getContext(), DEFAULT_TAG_HEIGHT);
  }

  public void setNewsAuthorText(String newsAuthorText) {

    mNewsAuthorText = newsAuthorText;
    if (TextUtils.isEmpty(newsAuthorText)) {
      Log.i(LOG_TAG, "newsAuthorText is empty !");
      return;
    }
    calculateText(newsAuthorText, mAuthorPaint, mAuthorTextAspect);
    Log.i(LOG_TAG, "newsAuthorText Aspect: " + mAuthorTextAspect);
  }

  public void setNewsIssueText(String newsIssueText) {

    mNewsIssueText = newsIssueText;

    Log.i(LOG_TAG, "newsIssueText getPaddingTop: " + getPaddingTop());

    if (TextUtils.isEmpty(newsIssueText)) {
      Log.i(LOG_TAG, "newsIssueText is empty !");
      return;
    }
    calculateText(newsIssueText, mIssuePaint, mIssueTextAspect);
    Log.i(LOG_TAG, "newsIssueText Aspect: " + mIssueTextAspect);
  }

  private void calculateText(@NonNull String text, Paint paint, FontAspect textAspect) {

    textAspect.aspectWidth = paint.measureText(text);
    final Paint.FontMetrics fontMetrics = paint.getFontMetrics();
    textAspect.top = fontMetrics.top;
    textAspect.ascent = fontMetrics.ascent;
    textAspect.descent = fontMetrics.descent;
    textAspect.bottom = fontMetrics.bottom;
    textAspect.aspectHeight = fontMetrics.descent - fontMetrics.ascent;

//    final Rect textBounds = new Rect();
//    paint.getTextBounds(text, 0, text.length(), textBounds);
//    textAspect.aspectHeight = textBounds.height();
  }

  public void setTagUri(String tagUri) {

    if (TextUtils.isEmpty(tagUri)) {
      if (mNewsTagDrawable != null) {
        invalidate();
        mNewsTagDrawable = null;
      }
      return;
    }
    if (mNewsTagDrawable != null
        && TextUtils.equals(tagUri, mTagUri)) {
      return;
    }
    mTagUri = tagUri;

    if (mTagTarget == null) {
      mTagTarget = new SimpleTarget<Bitmap>(mTagWidth, mTagHeight) {
        @Override
        public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {

          Log.i(LOG_TAG, "onResourceReady is run !");
          if (resource != null && !resource.isRecycled()) {
            Log.i(LOG_TAG, "onResourceReady is in -- getParent().isLayoutRequested: " + getParent().isLayoutRequested());
            mNewsTagDrawable = new BitmapDrawable(getResources(), resource);
            requestLayout();
          }
        }
      };
    }
    Glide.with(getContext().getApplicationContext()).load(mTagUri).asBitmap().into(mTagTarget);

    //This is test code
//      postDelayed(new Runnable() {
//        @Override
//        public void run() {
//          Glide.with(getContext().getApplicationContext()).load(mTagUri).asBitmap().into(mTagTarget);
//        }
//      }, 3000);
  }


  @Override
  public void freeMemory() {

  }

  @Override
  public void destroy() {
    if (mTagTarget != null) {
      Glide.clear(mTagTarget);
      mTagTarget = null;
    }
    if (mNewsTagDrawable != null) {
      mNewsTagDrawable = null;
    }
  }

  @Override
  protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    destroy();
  }

  private static final class FontAspect {

    public float aspectWidth;
    public float aspectHeight;
    public float top;
    public float ascent;
    public float descent;
    public float bottom;

    public String toString() {
      final String textFormat = "width: %s , height: %s , top: %s , ascent: %s , descent: %s , bottom: %s";
      return String.format(Locale.CHINESE, textFormat, aspectWidth, aspectHeight,
          top, ascent, descent, bottom);
    }
  }
}

































